package edgeTSQL

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commSql"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Json"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/String"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	"strings"
)

type MySQL struct {
}

func (e *MySQL) QueryRecords(tableName string, body map[string]interface{}) ([]*edgeEntity.DeviceSequenceEntity, error) {
	fields := e.buildFieldValue()
	args := make([]interface{}, 0)

	recordTime := Map.GetInt64(body, "recordTime", 0)
	deviceName := Map.GetString(body, "deviceName", "")
	order := strings.ToUpper(Map.GetString(body, "order", "ASC"))
	metricName := strings.ToUpper(Map.GetString(body, "metricName", "ASC"))
	pageSize := Map.GetInt(body, "pageSize", 10)

	sql := "SELECT * FROM " + tableName
	if order == "DESC" {
		sql += " WHERE create_time < " + String.ToString(recordTime)
	} else {
		sql += " WHERE create_time > " + String.ToString(recordTime)
	}
	if _, ok := body["deviceName"]; ok {
		sql += " AND device_name = ?"
		args = append(args, deviceName)
	}
	if _, ok := body["metricName"]; ok {
		sql += " AND metric_name = ?"
		args = append(args, metricName)
	}
	if _, ok := body["pageSize"]; ok {
		sql += " LIMIT " + String.ToString(pageSize)
	}

	list, err := Client.SQueryList(sql, fields, args)
	if err != nil {
		return nil, err
	}

	result := make([]*edgeEntity.DeviceSequenceEntity, 0)
	for _, data := range list {
		entity := edgeEntity.Type.DeviceSequenceEntity.NewEntity().(*edgeEntity.DeviceSequenceEntity)
		entity.BaseEntity.Id = Map.GetInt64(data, "id", 0)
		entity.BaseEntity.CreateTime = Map.GetInt64(data, "create_time", 0)
		entity.BaseEntity.UpdateTime = Map.GetInt64(data, "create_time", 0)
		entity.DeviceName = Map.GetString(data, "device_name", "")
		entity.MetricName = Map.GetString(data, "metric_name", "")
		entity.Timestamp = Map.GetInt64(data, "timestamp", 0)
		entity.DeviceValue = Json.BuildMapByJson(Map.GetString(data, "device_value", ""))

		result = append(result, entity)
	}

	return result, nil
}

func (e *MySQL) buildFieldValue() []commSql.FieldValue {
	fields := make([]commSql.FieldValue, 0)

	field := commSql.FieldValue{}
	field.Name = "id"
	field.Value = int64(0)
	fields = append(fields, field)

	field = commSql.FieldValue{}
	field.Name = "device_name"
	field.Value = ""
	fields = append(fields, field)

	field = commSql.FieldValue{}
	field.Name = "metric_name"
	field.Value = ""
	fields = append(fields, field)

	field = commSql.FieldValue{}
	field.Name = "timestamp"
	field.Value = int64(0)
	fields = append(fields, field)

	field = commSql.FieldValue{}
	field.Name = "device_value"
	field.Value = ""
	fields = append(fields, field)

	field = commSql.FieldValue{}
	field.Name = "create_time"
	field.Value = int64(0)
	fields = append(fields, field)

	return fields
}

func (e *MySQL) QueryTableNames(tableName string) ([]string, error) {
	fields := make([]commSql.FieldValue, 0)
	field := commSql.FieldValue{}
	field.Name = "table_name"
	field.Value = ""
	fields = append(fields, field)

	sql := "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_name LIKE '" + tableName + "_%' "
	list, err := Client.QueryList(sql, fields)
	if err != nil {
		return nil, err
	}

	result := make([]string, 0)
	for _, row := range list {
		result = append(result, row["table_name"].(string))
	}

	return result, nil
}

func (e *MySQL) InsertRecord(tableName, sql string, values []interface{}) (int64, error) {

	// 执行SQL语句
	id, err := Client.Exec(sql, values)
	if err == nil {
		return id, nil
	}

	// 检查：是否为数据库表不存在的原因，导致的插入失败
	if !strings.Contains(err.Error(), "doesn't exist") {
		return id, nil
	}

	// 这里可以创建表
	err = e.CreateTable(tableName)
	if err != nil {
		return 0, err
	}

	// 再次执行插入语句
	return Client.Exec(sql, values)
}

func (e *MySQL) DropTable(tableName string) error {
	sql := "DROP TABLE " + tableName
	_, err := Client.Exec(sql, nil)
	return err
}

func (e *MySQL) CreateTable(tableName string) error {
	sql := `
CREATE TABLE "tb_sequence_20250910" (
	"id" BIGINT NOT NULL AUTO_INCREMENT COMMENT '序号',
	"device_name" VARCHAR(50) NULL DEFAULT NULL COMMENT '设备名称' COLLATE 'utf8mb4_0900_ai_ci',
	"metric_name" VARCHAR(50) NULL DEFAULT NULL COMMENT '指标名称' COLLATE 'utf8mb4_0900_ai_ci',
	"timestamp" BIGINT NULL DEFAULT NULL COMMENT '时间戳',
	"device_value" JSON NULL DEFAULT NULL COMMENT '设备数值',
	"create_time" BIGINT NULL DEFAULT NULL COMMENT '创建时间',
	PRIMARY KEY ("id") USING BTREE,
	UNIQUE INDEX "device_name_metric_name_timestamp" ("device_name", "metric_name", "timestamp") USING BTREE,
	INDEX "device_name" ("device_name") USING BTREE,
	INDEX "metric_name" ("metric_name") USING BTREE,
	INDEX "timestamp" ("timestamp") USING BTREE
)
COMMENT='时序列表'
COLLATE='utf8mb4_0900_ai_ci'
ENGINE=InnoDB
;
`
	sql = strings.ReplaceAll(sql, "\"", "`")

	// 创建数据库表
	return e.ExecSQL(sql, tableName, "tb_sequence_20250910")
}

func (e *MySQL) ExecSQL(sql, tableName, tableNameTag string) error {
	sql = strings.ReplaceAll(sql, "tb_sequence_20250910", tableName)
	// 创建数据库表
	_, err := Client.Exec(sql, nil)
	return err
}
